package service

import (
	"fmt"
	"choujiang/common/consts"
	"choujiang/common/db"
	"choujiang/common/models"
	"choujiang/common/utils"
	"encoding/json"
	"strconv"
	"time"
	"github.com/go-redis/redis"
	"strings"
)

const (
	SIGN_UP_KEY        = "BoxKey::leyouboxsignup_"
	SING_UP_NUMBER_KEY = "BoxKey::leyouboxcontinuenumber_"
	PLAY_NUMBER_KEY    = "BoxKey::leyouboxplaynumber_"
	PLAY_FOOTPRINT     = "BoxKey::leyouboxplayfootprint_"
	ADD_POINT          = 10              //增加积分值
	MAX_POINT          = 100             //最大增长值
	CYCLE_DATE         = 6               //循环日期
	EXPIRE_MINUS       = time.Hour * 192 //过期时间8天
	THIRD_PLAY_REWARD  = 10              //玩3款小游戏奖励
	FIVE_PLAY_REWARD   = 10              //玩5款小游戏奖励
)

type SignUpList struct {
	TodaySign    int   `json:"todaySign"`
	ContinueDate int   `json:"continueDate"`
	RewardPoint  []int `json:"rewardPoint"`
}

/**
每日签到
*/
func DailySignUp(user *model.User) *utils.ErrorType {
	signUpKey := SIGN_UP_KEY + strconv.FormatInt(user.Id, 10)
	reInt := db.MainRedisClient.Exists(signUpKey)
	fmt.Printf("reInt is %d", reInt)
	if reInt.Val() == 0 { //不存在
		db.MainRedisClient.SAdd(signUpKey, todayUnix())
		addUserPoint(user, signUpKey) //增加用户积分
	} else { //存在
		existMember := db.MainRedisClient.SIsMember(signUpKey, todayUnix())
		fmt.Printf("val is %d", existMember.Val())
		if existMember.Val() { //今日已签到
			return consts.ErrAlreadySignUp
		} else { //今日未签到
			db.MainRedisClient.SAdd(signUpKey, todayUnix())
			addUserPoint(user, signUpKey) //增加用户积分
		}
	}
	return nil
}

func GetSignUpInfo(user *model.User) (int, int) {
	reward := 0
	nextReward := 0
	signUpKey := SIGN_UP_KEY + strconv.FormatInt(user.Id, 10)
	signNumberKey := SING_UP_NUMBER_KEY + strconv.FormatInt(user.Id, 10)
	existMember := db.MainRedisClient.SIsMember(signUpKey, yesterdayUnix())
	signNum := db.MainRedisClient.Get(signNumberKey)
	intSignNum, _ := strconv.Atoi(signNum.Val())
	rewardList := []int{10, 20, 30, 40, 50, 60, 100}
	if intSignNum <= 7 {
		if intSignNum == 0 {
			if existMember.Val() {
				reward = rewardList[len(rewardList)-1]
			} else {
				reward = rewardList[0]
			}
		} else {
			reward = rewardList[intSignNum-1]
		}
		if intSignNum <= 6 {
			nextReward = rewardList[intSignNum]
		} else {
			nextReward = rewardList[len(rewardList)-1]
		}
	} else {
		reward = rewardList[len(rewardList)-1]
		nextReward = rewardList[len(rewardList)-1]
	}
	return reward, nextReward
}

func todayUnix() string {
	timeStr := time.Now().In(time.Local).Format("2006-01-02")
	return timeStr
}

func yesterdayUnix() string {
	t := time.Now().In(time.Local).AddDate(0, 0, -1)
	timeStr := t.Format("2006-01-02")
	return timeStr
}

/**
用户增加积分
*/
func addUserPoint(user *model.User, signUpKey string) {
	signNumberKey := SING_UP_NUMBER_KEY + strconv.FormatInt(user.Id, 10)
	existMember := db.MainRedisClient.SIsMember(signUpKey, yesterdayUnix())
	existNumber := db.MainRedisClient.Exists(signNumberKey)
	addPoint := 0 //初始积分值

	if existNumber.Val() == 0 { //没有连续签到数量
		db.MainRedisClient.Set(signNumberKey, 1, EXPIRE_MINUS)
		addPoint = ADD_POINT
	} else { //有连续签到数量
		if existMember.Val() { //昨天签到了
			signNum := db.MainRedisClient.Get(signNumberKey)
			intSignNum, _ := strconv.Atoi(signNum.Val())
			if intSignNum < CYCLE_DATE { //七天以内
				addPoint = (intSignNum + 1) * ADD_POINT
				db.MainRedisClient.Incr(signNumberKey) //连续签到数加1
			} else { //第七天
				addPoint = MAX_POINT
				db.MainRedisClient.Set(signNumberKey, 0, EXPIRE_MINUS)
			}
		} else { //昨天没签到
			db.MainRedisClient.Set(signNumberKey, 1, EXPIRE_MINUS)
			addPoint = ADD_POINT
		}
	}
	_, err := db.MysqlEngine.Exec("update user_extra set point = point + ? where user_id = ?", addPoint, user.Id)
	if err != nil {
		fmt.Printf("Add user point err:", err)
	}
	//记录任务完成信息
	db.Mgo.CompleteTask(user.Id, db.SIGN_UP_TASK, true)
	//记录金币来源
}

/**
获取用户签到详情
*/
func GetSignUpList(user *model.User) (SignUpList, error) {
	signUpKey := SIGN_UP_KEY + strconv.FormatInt(user.Id, 10)
	signNumberKey := SING_UP_NUMBER_KEY + strconv.FormatInt(user.Id, 10)
	existNumber := db.MainRedisClient.Exists(signNumberKey)
	dataList := SignUpList{}
	rewardList := []int{10, 20, 30, 40, 50, 60, 100}
	if existNumber.Val() == 0 { //没有连续签到数量
		dataList.ContinueDate = 0
	} else {
		signNum := db.MainRedisClient.Get(signNumberKey)
		intSignNum, _ := strconv.Atoi(signNum.Val())
		dataList.ContinueDate = intSignNum
	}
	todaySign := db.MainRedisClient.SIsMember(signUpKey, todayUnix())
	if todaySign.Val() {
		dataList.TodaySign = 1
	} else {
		dataList.TodaySign = 0
	}
	dataList.RewardPoint = rewardList
	return dataList, nil
}

/**
 玩游戏次数任务
 */
func PlayNumberTask(log model.Log) {
	user := model.GetUserByUniqueId(log.UniqueId)
	if log.FromGame != "" && log.FromGame != "leyoubox" { //第二版盒子
		playKey := PLAY_NUMBER_KEY + log.FromGame + strconv.FormatInt(user.Id, 10)
		keyExist := db.MainRedisClient.Exists(playKey)
		if keyExist.Val() == 0 { //没有游玩记录
			db.MainRedisClient.SAdd(playKey, log.ToGame)
			//记录任务完成信息
			db.Mgo.CompleteNewTask(user.Id, db.PLAY_SIX_GAME_TASK, false)
		} else { //有游玩记录
			keyExist := db.MainRedisClient.SIsMember(playKey, log.ToGame)
			if !keyExist.Val() { //没有玩过
				keyNum := db.MainRedisClient.SCard(playKey)
				if keyNum.Val() == 7 { //任务完成
					if db.Mgo.TakeRedPack(user.Id, 1) { //完成了两个任务，领取3元红包
						_, err := db.MysqlEngine.Exec("update user_extra set balance = balance + ? where user_id = ?", 3, user.Id)
						if err != nil {
							fmt.Printf(" err is %s", err)
						}
					}
					//记录任务完成信息
					db.Mgo.CompleteNewTask(user.Id, db.PLAY_SIX_GAME_TASK, true)
				} else {
					db.Mgo.CompleteNewTask(user.Id, db.PLAY_SIX_GAME_TASK, false)
				}
				db.MainRedisClient.SAdd(playKey, log.ToGame)
			}
		}
	} else { //第一版盒子
		playKey := PLAY_NUMBER_KEY + strconv.FormatInt(user.Id, 10)
		keyExist := db.MainRedisClient.Exists(playKey)
		if keyExist.Val() == 0 { //没有游玩记录
			var playSlice []string
			newSlice := append(playSlice, log.ToGame)
			jsonSlice, _ := json.Marshal(newSlice)
			db.MainRedisClient.HSet(playKey, utils.TodayUnix(), jsonSlice)
			//记录任务完成信息
			db.Mgo.CompleteTask(user.Id, db.PLAY_THREE_GAME_TASK, false)
		} else { //有游玩记录
			toDayExist := db.MainRedisClient.HExists(playKey, utils.TodayUnix())
			if toDayExist.Val() { //今天有玩过
				var jsonSlice []string
				stringVal := db.MainRedisClient.HGet(playKey, utils.TodayUnix())
				json.Unmarshal([]byte(stringVal.Val()), &jsonSlice)
				if !utils.StringInSlice(jsonSlice, log.ToGame) {
					if len(jsonSlice) >= 3 {
						db.Mgo.SuplementTask(user.Id, db.PLAY_THREE_GAME_TASK)
					}
					if len(jsonSlice) >= 5 {
						db.Mgo.SuplementTask(user.Id, db.PLAY_FIVE_GAME_TASK)
					}
					switch len(jsonSlice) {
					case 2: //完成游玩3次的任务
						completeTask(user.Id, THIRD_PLAY_REWARD)
						//记录任务完成信息
						db.Mgo.CompleteTask(user.Id, db.PLAY_THREE_GAME_TASK, true)
						//记录金币来源
					case 4: //完成游玩5次的任务
						completeTask(user.Id, FIVE_PLAY_REWARD)
						//记录任务完成信息
						db.Mgo.CompleteTask(user.Id, db.PLAY_FIVE_GAME_TASK, true)
						//记录金币来源
					default:
						db.Mgo.CompleteTask(user.Id, db.PLAY_FIVE_GAME_TASK, false)
					}
				}
				newSlice := append(jsonSlice, log.ToGame)
				newJsonSlice, _ := json.Marshal(newSlice)
				db.MainRedisClient.HSet(playKey, utils.TodayUnix(), newJsonSlice)
			} else { //今天没玩过
				var playSlice []string
				newSlice := append(playSlice, log.ToGame)
				jsonSlice, _ := json.Marshal(newSlice)
				db.MainRedisClient.HSet(playKey, utils.TodayUnix(), jsonSlice)
				//记录任务完成信息
				db.Mgo.CompleteTask(user.Id, db.PLAY_THREE_GAME_TASK, false)
			}
		}
		//记录游戏足迹
		RecordFootPrint(log, user.Id)
	}
}

/**
 记录游戏足迹
 */
func RecordFootPrint(log model.Log, userId int64) {
	footKey := PLAY_FOOTPRINT + strconv.FormatInt(userId, 10)
	keyExist := db.MainRedisClient.Exists(footKey)
	if keyExist.Val() == 0 {
		defer db.MainRedisClient.Expire(footKey, time.Hour*72)
	}
	footStruct := redis.Z{
		Score:  float64(time.Now().Unix()),
		Member: log.ToGame,
	}
	db.MainRedisClient.ZAdd(footKey, footStruct)
	reAdd := db.MainRedisClient.ZAdd(footKey, footStruct)
	if reAdd.Val() == 0 {
		fmt.Println("RecordFootPrint err")
	}
}

/**
 返回游戏足迹
 */
func GetFootprint(user *model.User) []model.Game {
	footPrint := make([]model.Game, 0)
	footKey := PLAY_FOOTPRINT + strconv.FormatInt(user.Id, 10)
	keyExist := db.MainRedisClient.Exists(footKey)
	if keyExist.Val() != 0 {
		reSlice := db.MainRedisClient.ZRevRange(footKey, 0, time.Now().Unix())
		utils.ReverseSlice(reSlice.Val())
		strSlice := strings.Replace(strings.Trim(fmt.Sprint(reSlice), "[]"), " ", ",", -1)
		err := db.MysqlEngine.Cols("id", "name", "game_id", "wx_app_id", "app_type", "icon", "desc").In("game_id", reSlice.Val()).OrderBy("find_in_set(game_id, '" + strSlice + "')").Find(&footPrint)
		if err != nil {
			fmt.Printf("RecordFootPrint err %s", err)
		}
		for i := 0; i < len(footPrint); i++ {
			footPrint[i].Icon = utils.AddPrefix(footPrint[i].Icon)
		}
	}
	return footPrint
}

/**
 领取带领取的推荐游戏奖励
 */
func ReceiveRecommend(user *model.User, gameId string) {
	val := db.MainRedisClient.SIsMember(RECOMMEND_TO_RECEIVE_KEY+gameId+utils.TodayUnix(), user.Id)
	if val.Val() {
		//用户获取金币奖励
		//RecommendGameReward(user, gameId)
		//清除待领取用户记录
		err := db.MainRedisClient.SRem(RECOMMEND_TO_RECEIVE_KEY+gameId+utils.TodayUnix(), user.Id).Err()
		if err != nil {
			fmt.Printf("ReceiveRecommend err: %s", err)
		}
	}
	return
}
